package context;

import annotation.Order;
import exception.SoiRuntimeException;
import load.BeanLoader;

import java.util.Comparator;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @className: SoiHolder
 * @author: ocxz1
 * @date: 2025/4/2 上午1:17
 * @Version: 1.0
 * @description: soi
 */
public class SoiHolder {

    private static final SoiHolder soiHolder = SingletonHolder.INSTANCE;

    private static class SingletonHolder {
        private static final SoiHolder INSTANCE = new SoiHolder();
    }

    private CopyOnWriteArrayList<BeanLoader> beanLoaderList;

    private SoiHolder() {

    }

    public static void setBeanLoader(BeanLoader beanLoader) {
        if (soiHolder.beanLoaderList == null) {
            soiHolder.beanLoaderList = new CopyOnWriteArrayList<>();
        }

        if (beanLoader.isUnique()) {
            soiHolder.beanLoaderList.clear();
            soiHolder.beanLoaderList.add(beanLoader);
        } else {
            soiHolder.beanLoaderList.add(beanLoader);

            // 添加完后排序
            sortBeanLoaders();
        }
    }

    public static void sortBeanLoaders() {
        if (soiHolder.beanLoaderList != null) {
            if (soiHolder.beanLoaderList.size() == 1) {
                return;
            }

            // 进行排序
            soiHolder.beanLoaderList.sort(Comparator.comparingInt(beanLoader -> {
                Order order = beanLoader.getClass().getAnnotation(Order.class);
                return order != null ? order.value() : Integer.MAX_VALUE;
            }));
        }
    }

    public static Object getBean(String beanName) {
        for (BeanLoader beanLoader : soiHolder.beanLoaderList) {
            try {
                Object bean = beanLoader.getBean(beanName);
                if (bean != null) {
                    return bean;
                }
            } catch (Exception e) {
                // 忽略异常
            }
        }
        throw new SoiRuntimeException("beanName:" + beanName + "获取失败");
    }

    public static <T> T getBean(Class<T> tClass) {
        for (BeanLoader beanLoader : soiHolder.beanLoaderList) {
            try {
                T bean = beanLoader.getBean(tClass);
                if (bean != null) {
                    return bean;
                }
            } catch (Exception e) {
                // 忽略异常
            }
        }
        throw new SoiRuntimeException("tClass:" + tClass.getName() + "获取失败");
    }
}
